/* Copyright 2009 CtrlSpace Platform
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 * 		http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * 
 * Contributor(s):
 * 	Marc Obaldo (marcklaser@gmail.com)
 */

dojo.provide("ctrlspace.ui.editor.EditorPane");
dojo.require("ctrlspace.codemirror.codemirror");
dojo.require("ctrlspace.ui.editor.CodeAssist");
dojo.require("ctrlspace.ui.tools.ShortcutDialog");
dojo.declare("ctrlspace.ui.editor.EditorPane", dijit.layout.ContentPane, {	
	constructor: function(/* Object*/ options) {
		this.codemirror = null;
		this.keyBinding = null;
		this.blurBinding = null;
		this.activeNode = null;
		this.cursorPos = {line: null, character: 0};
		this.isEditorDirty = false;
		this.isEditorTitleDirty = false;
	},
	
	// Methods
	beginCodeAssist: function() {
//		this.setCursorPosition();
		var pos = this.getCursorPosition();
		var lineHandle = pos.line;
		var line = this.getEditor().lineNumber(lineHandle);
		var lineContent = this.getEditor().lineContent(lineHandle);
		
		var lastSpaceIndex = 0;
		for (i = 0; i < pos.character; i++) {
			if (lineContent.charAt(i) == " ") {
				lastSpaceIndex = i;
			}
		}

		var identifier = "";
		for (i = lastSpaceIndex + 1; i < pos.character - 1; i++) {
			identifier += lineContent.charAt(i);
		}
		
		var xhr = dojo.xhrGet({
			url: ctrlspace.config.projectManagerUrl,
			content: {
				command: "auto_complete",
				codeState: this.getEditor().getCode(),
				lineNumber: line,
				variableName: identifier
			},
			handleAs: "json",
			sync: true
		});
		
		xhr.addCallback(dojo.hitch(this, this.codeAssistSuccess));
	},
	
	codeAssistSuccess: function(assists) {
		var store = new dojo.data.ItemFileReadStore({
			data: assists
		});
		
		var filteringSelect = new ctrlspace.ui.editor.CodeAssist({
			name: "codeAssist",
			searchAttr: "label",
			store: store,
			value: assists.items[0].label,
			style: "width: 350px",
			selectOnClick: true
		});
		
		var node = this.getActiveNode();
		var x = node.offsetLeft + node.offsetWidth - node.offsetParent.scrollLeft;
		var y = node.offsetTop + node.offsetHeight - node.offsetParent.scrollTop;
		
		var pos = dojo.position(this.domNode);
		x += pos.x + 2;
		y += pos.y - 10;
		
		dijit.popup.open({
		    parent: this,
		    popup: filteringSelect,
		    x: x,
		    y: y,
		    onExecute: dojo.hitch(this, function() {
				dijit.popup.close(filteringSelect);
		        var item = filteringSelect.item;
		        var completion = item.label[0].substring(0, item.label[0].indexOf(":") - 1);
		        
		        var pos = this.getCursorPosition();
		        this.getEditor().insertIntoLine(pos.line, pos.character, completion);
		        
		        if (item.parameters.length > 0) {
		        	var startOffset = pos.character + item.methodName[0].length + 1;
		        	var endOffset = startOffset + item.parameters[0].length;
		        	this.getEditor().selectLines(pos.line, startOffset, pos.line, endOffset);
		        }
			}),

		    onCancel: function() {
		        dijit.popup.close(filteringSelect);
		    }
		});
	},
	
	focusOnLastEditorPosition: function() {
		var pos = this.getCursorPosition();
		this.codemirror.focus();
		if (pos != null && pos.line != null && pos.character != null) {
			this.codemirror.selectLines(pos.line, pos.character);
		}
	},

	saveEditor: function() {
		IDE.getUI().getEditors().saveEditor(this);
	},

	// Events
	onClose: function() {
		var close = true;

		if (this.isEditorDirty == true) {
			close = confirm("Exit without saving changes?");
		}
		
		if (close) {
			dojo.disconnect(this.keyBinding);
			this.keyBinding = null;
			
			dojo.disconnect(this.blurBinding);
			this.blurBinding = null;
			
			this.saveEditor();
			IDE.getUI().getEditors().closeEditor(this);
		}
		
		return close;
	},
	
	onCursorActivity: function(node) {
		this.activeNode = node;
	},

	onEditorChange: function() {
		this.setCursorPosition();
		this.setIsDirty(true);
	},

	onEditorKeyPress: function(event) {
		// Ctrl+(Shift)+TAB -- Move to next tab
		if (event.charOrCode == dojo.keys.TAB && event.ctrlKey) {
			dojo.stopEvent(event);
			
			var forward = event.shiftKey;
			var next = IDE.getUI().getEditors()._adjacent(!forward);
			IDE.getUI().getEditors().selectChild(next);
		}
		// Ctrl+S -- Save
		else if (event.charOrCode == 's' && event.ctrlKey) {
			dojo.stopEvent(event);
			this.saveEditor();
		}
		// Ctrl+Space -- Ctrl+Space!
		else if (event.charOrCode == " " && event.ctrlKey) {
			dojo.stopEvent(event);
			this.beginCodeAssist();
		}
		// Alt+Shift+X -- Shortcuts and Tools!
		else if (event.charOrCode == 'X' && event.altKey && event.shiftKey) {
			var tooltip = new ctrlspace.ui.tools.ShortcutDialog();
			
			dijit.popup.open({
				parent: this,
			    popup: tooltip,
			    x: 10,
			    y: 10,
			    onExecute: dojo.hitch(this, function() {
					dijit.popup.close(tooltip);
				}),
			    onCancel: function() {
			        dijit.popup.close(tooltip);
			    }
			});
			
			console.log(tooltip);
		}
		// No action
		else {
			
		}
	},
	
//	onFocus: function() {
//		this.focusOnLastEditorPosition();
//	},
	
	onSelected: function(child) {
		if (child == this) {
			this.focusOnLastEditorPosition();
		}
	},
	
	// Getters and setters
	setTitle: function(newTitle) {
		this.title = newTitle;
		this.controlButton.containerNode.innerHTML = newTitle || "";
	},
	
	getTitle: function() {
		return this.title;
	},
	
	setEditor: function(content) {
		this.codemirror = content;
		this.keyBinding = dojo.connect(this.codemirror.win.document, "onkeypress",
				dojo.hitch(this, this.onEditorKeyPress));
		this.blurBinding = dojo.connect(this.codemirror.win.document, "onblur",
				dojo.hitch(this, this.setCursorPosition));
	},
	
	getEditor: function() {
		return this.codemirror;
	},
	
	setCursorPosition: function() {
		this.cursorPos = this.codemirror.cursorPosition();
	},
	
	getCursorPosition: function() {
		return this.cursorPos;
	},
	
	setIsDirty: function(isDirty) {
		this.isEditorDirty = isDirty;
		this.isEditorTitleDirty = isDirty;

		if (!isDirty) {
			if (this.getTitle().charAt(0) == "*") {
				this.setTitle(this.getTitle().substring(1));
			}
		} else if (this.getTitle().charAt(0) != "*") {
			this.setTitle("*" + this.getTitle());
		}
	},
	
	getIsDirty: function() {
		return this.isEditorDirty;
	},
	
	getActiveNode: function() {
		return this.activeNode;
	}
});